package com.atguigu03.refectapply.apply3;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class test {
    /*调用具体的属性*/
    @Test
    public void t1() throws Exception {
        Class class1=Person.class;

        Person p1 = (Person) class1.newInstance();

        Field field1=class1.getField("age");

        System.out.println(field1.get(p1));

        field1.set(p1,3);
        System.out.println(field1.get(p1));
    }
    //private属性的获取  可视为任何属性的通用获取方法
    @Test
    public void t2() throws Exception {
        Class class1=Person.class;

        Person p1=(Person)class1.newInstance();

        //1.通过Class实例调用getDeclaredField(String fieldName)，获取运行时类指定名的属性
        Field field1=class1.getDeclaredField("name");
        //2. setAccessible(true):确保此属性是可以访问的
        field1.setAccessible(true);
        //3．通过Filed类的实例调用get(0bject obj)（获取的操作)
        // 或set(0bject obj,0bject value)（设置的操作进行操作。
        field1.set(p1,"tom");
        System.out.println(field1.get(p1));

    }

    //static属性的获取
    @Test
    public void t3() throws Exception {
        Class class1=Person.class;

      //  Person p1=(Person)class1.newInstance();

        //1.通过Class实例调用getDeclaredField(String fieldName)，获取运行时类指定名的属性
        Field field1=class1.getDeclaredField("infor");
        //2. setAccessible(true):确保此属性是可以访问的
        field1.setAccessible(true);
        //3．通过Filed类的实例调用get(0bject obj)（获取的操作)
        // 或set(0bject obj,0bject value)（设置的操作进行操作。
        field1.set(Person.class,"tom");
        System.out.println(field1.get(Person.class));

    }


    //调用指定的方法
    @Test
    public void t4() throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class class1=Person.class;

        Person person =(Person) class1.newInstance();
        //1.通过Class的实例调用getDeclaredMethod(String methodName ,Class ... args)，获取指定的方法
        Method method = class1.getDeclaredMethod("method", String.class, int.class);
        //2. setAccessible(true):确保此方法是可访问的
        method.setAccessible(true);
        //3.通过Me thod实例调用invoke(Object obj,0bject ... objs),即为对Nethod对应的方法的调用。
        // invoke()的返回值即为Method对应的方法的返回值
        method.invoke(person,"tom",10);
        
    }
    //static方法
    @Test
    public void t5() throws Exception{
        Class class1=Person.class;

        Method method1 = class1.getDeclaredMethod("method1", String.class, int.class);

        method1.setAccessible(true);

        method1.invoke(null,"tim",45);
    }

    //调用构造器  private Person(String name, int age)
    @Test
    public void t6() throws Exception{
        Class class1=Person.class;
        //1.通过Class的实例调用getDeclaredConstructor(Class ... args)，获取指定参数类型的构造器
        Constructor declaredConstructor = class1.getDeclaredConstructor(String.class,int.class);
        //2.setAccessible(true):确保此构造器是可以访问的
        declaredConstructor.setAccessible(true);
        //3 .通过Constructor实例调用newInstance(0bject ... objs)，返回一个运行时类的实例。
        Person person=(Person) declaredConstructor.newInstance("tom",12);

        System.out.println(person);


    }
}
